/*
 * @Author: Dorange.Wang
 * @Date: 2021-04-26 17:48:25
 * @LastEditors: your name
 * @LastEditTime: 2021-06-28 16:59:00
 * @Description: file content
 */
import { Message } from 'element-ui'
import { VARIABLE_BUILT_IN_REG } from '@/utils/reg'
export const DEFAULT_SUBMIT_TASK_ID = '__initiator__'
export const DEFAULT_SCRIPT_TASK_ID_PREFIX = 'Script_'
export const DEFAULT_GATEWAY_TYPE_SUBFIX = 'Gateway'
/**
 * 节点配置映射
 */
const eventStyle = {
  width: 44,
  height: 44,
  x: -5,
  y: -5
}
const eventBgStyle = {
  class: 'render',
  cx: 17,
  cy: 17,
  r: 17,
  fill: 'white'
}
const taskStyle = {
  width: 20,
  height: 20,
  x: 6,
  y: 6
}
const gatewayStyle = {
  width: 60,
  height: 60,
  x: -5,
  y: -5
}
const gatewayBgStyle = {
  class: 'render',
  cx: 24,
  cy: 24,
  r: 24,
  fill: 'white'
}
export const elementConfig = {
  // 'bpmn:bpmn:StartEvent': {
  //   icon: 'el-icon-video-play',
  //   unicode: '&#xe7c0'
  // },
  'bpmn:SubmitTask': {
    icon: 'el-icon-edit-outline',
    unicode: '&#xe764',
    style: taskStyle
  },
  'bpmn:UserTask': {
    icon: 'el-icon-user',
    unicode: '&#xe6e3',
    style: taskStyle

  },
  'bpmn:ServiceTask': {
    icon: 'el-icon-setting',
    unicode: '&#xe6ca',
    style: taskStyle

  },
  'bpmn:ServiceScriptTask': {
    icon: 'el-icon-document-copy',
    unicode: '&#xe787',
    style: taskStyle

  },
  'bpmn:ReceiveTask': {
    icon: 'el-icon-message',
    unicode: '&#xe72b',
    style: taskStyle

  },
  'bpmn:ExclusiveGateway': {
    icon: 'el-icon-circle-close',
    unicode: '&#xe78d',
    bgStyle: gatewayBgStyle,
    style: gatewayStyle

  },
  'bpmn:ParallelGateway': {
    icon: 'el-icon-circle-plus-outline',
    unicode: '&#xe723',
    bgStyle: gatewayBgStyle,
    style: gatewayStyle
  },
  'bpmn:InclusiveGateway': {
    icon: 'el-icon-remove-outline',
    unicode: '&#xe722',
    bgStyle: gatewayBgStyle,
    style: gatewayStyle
  },
  'bpmn:EndEvent': {
    icon: 'el-icon-video-pause',
    unicode: '&#xe7c1',
    bgStyle: eventBgStyle,
    style: eventStyle
  }
}

/**
 * 下载svg时插入图标资源
 */
export const additionalSymbolTags =
`
<symbol id="hanma-bpmn-icon-edit-outline" viewBox="0 0 1024 1024"><path d="M832 512q0-14.016 8.992-23.008T864 480t23.008 8.992T896 512v352q0 14.016-8.992 23.008T864 896H160q-14.016 0-23.008-8.992T128 864V160q0-14.016 8.992-23.008T160 128h352q14.016 0 23.008 8.992T544 160t-8.992 23.008T512 192H192v640h640V512z m-361.984 42.016l52.992-7.008L847.008 222.016q12.992-12.992 8.512-30.496t-22.496-22.496-31.008 8L477.024 501.024zM892 132q28 28 28 67.488t-28 68.512L560.992 599.008q-8 8-19.008 10.016l-104.992 15.008q-16 2.016-27.008-9.504t-8.992-27.488L416 482.048q0.992-11.008 8.992-18.016L756.992 132.032q28.992-28 67.488-28t67.488 28z"  ></path></symbol><symbol id="hanma-bpmn-icon-circle-close" viewBox="0 0 1024 1024"><path d="M467.008 512l-91.008-90.016q-8.992-10.016-8.992-23.008t9.504-22.496 22.496-9.504 23.008 8.992l90.016 91.008 90.016-91.008q14.016-12.992 31.488-8t22.496 22.496-8 31.488l-91.008 90.016 91.008 90.016q12.992 14.016 8 31.488t-22.496 22.496-31.488-8l-90.016-91.008-90.016 91.008q-10.016 8.992-23.008 8.992t-22.496-9.504-9.504-22.496 8.992-23.008zM512 896q163.008-4 271.488-112.512T896 512q-4-163.008-112.512-271.488T512 128q-163.008 4-271.488 112.512T128 512q4 163.008 112.512 271.488T512 896z m0 64q-190.016-4.992-316.512-131.488T64 512q4.992-190.016 131.488-316.512T512 64q190.016 4.992 316.512 131.488T960 512q-4.992 190.016-131.488 316.512T512 960z"  ></path></symbol><symbol id="hanma-bpmn-icon-circle-plus-outline" viewBox="0 0 1024 1024"><path d="M352 480h320q14.016 0 23.008 8.992T704 512t-8.992 23.008T672 544H352q-14.016 0-23.008-8.992T320 512t8.992-23.008T352 480z m128 192V352q0-14.016 8.992-23.008T512 320t23.008 8.992T544 352v320q0 14.016-8.992 23.008T512 704t-23.008-8.992T480 672z m32 224q163.008-4 271.488-112.512T896 512q-4-163.008-112.512-271.488T512 128q-163.008 4-271.488 112.512T128 512q4 163.008 112.512 271.488T512 896z m0 64q-190.016-4.992-316.512-131.488T64 512q4.992-190.016 131.488-316.512T512 64q190.016 4.992 316.512 131.488T960 512q-4.992 190.016-131.488 316.512T512 960z"  ></path></symbol><symbol id="hanma-bpmn-icon-document-copy" viewBox="0 0 1024 1024"><path d="M128 320v576h576V320H128zM96 256h640q14.016 0 23.008 8.992T768 288v640q0 14.016-8.992 23.008T736 960H96q-14.016 0-23.008-8.992T64 928V288q0-14.016 8.992-23.008T96 256z m864-160v704q0 14.016-8.992 23.008T928 832h-96v-64h64V128H384v64h-64V96q0-14.016 8.992-23.008T352 64h576q14.016 0 23.008 8.992T960 96zM256 672h320v64H256v-64z m0-192h320v64H256v-64z"  ></path></symbol><symbol id="hanma-bpmn-icon-message" viewBox="0 0 1024 1024"><path d="M128 224v512q0.992 27.008 19.008 44.992T192 800h640q27.008-0.992 44.992-19.008T896 736V224H128z m0-64h768q27.008 0.992 44.992 19.008T960 224v512q-0.992 54.016-37.504 90.496T832 864H192q-54.016-0.992-90.496-37.504T64 736V224q0.992-27.008 19.008-44.992T128 160z m776 64l-247.008 283.008q-28 31.008-65.504 48T512 572t-79.488-16.992-65.504-48L120 224h784zM204.992 224L416 464.992q18.016 20.992 43.008 32t52.992 11.008 52.992-11.008 43.008-32L819.008 224H204.992z"  ></path></symbol><symbol id="hanma-bpmn-icon-remove-outline" viewBox="0 0 1024 1024"><path d="M352 480h320q14.016 0 23.008 8.992T704 512t-8.992 23.008T672 544H352q-14.016 0-23.008-8.992T320 512t8.992-23.008T352 480z m160 416q163.008-4 271.488-112.512T896 512q-4-163.008-112.512-271.488T512 128q-163.008 4-271.488 112.512T128 512q4 163.008 112.512 271.488T512 896z m0 64q-190.016-4.992-316.512-131.488T64 512q4.992-190.016 131.488-316.512T512 64q190.016 4.992 316.512 131.488T960 512q-4.992 190.016-131.488 316.512T512 960z"  ></path></symbol><symbol id="hanma-bpmn-icon-user" viewBox="0 0 1024 1024"><path d="M512 512q82.016-2.016 136-56T704 320q-2.016-82.016-56-136T512 128q-82.016 2.016-136 56T320 320q2.016 82.016 56 136T512 512z m0 64q-108.992-3.008-180.992-75.008T256 320q3.008-108.992 75.008-180.992T512 64q108.992 3.008 180.992 75.008T768 320q-3.008 108.992-75.008 180.992T512 576z m320 320v-96q-0.992-40.992-28-68T736 704H288q-40.992 0.992-68 28T192 800v96q0 14.016-8.992 23.008T160 928t-23.008-8.992T128 896v-96q2.016-68 47.008-112.992T288 640h448q68 2.016 112.992 47.008T896 800v96q0 14.016-8.992 23.008T864 928t-23.008-8.992T832 896z"  ></path></symbol><symbol id="hanma-bpmn-icon-video-pause" viewBox="0 0 1024 1024"><path d="M512 64q190.016 4.992 316.512 131.488T960 512q-4.992 190.016-131.488 316.512T512 960q-190.016-4.992-316.512-131.488T64 512q4.992-190.016 131.488-316.512T512 64z m0 832q163.008-4 271.488-112.512T896 512q-4-163.008-112.512-271.488T512 128q-163.008 4-271.488 112.512T128 512q4 163.008 112.512 271.488T512 896z m-96-544q32 0 32 32v256q0 32-32 32t-32-32v-256q0-32 32-32z m192 0q32 0 32 32v256q0 32-32 32t-32-32v-256q0-32 32-32z"  ></path></symbol><symbol id="hanma-bpmn-icon-setting" viewBox="0 0 1024 1024"><path d="M624.992 64l222.016 128-43.008 75.008q22.016 26.016 40 56.992t30.016 64h86.016v256h-86.016q-24 67.008-70.016 120.992l43.008 75.008-222.016 128-43.008-75.008q-70.016 12.992-140 0l-43.008 75.008-222.016-128 43.008-75.008q-23.008-27.008-40.512-57.504t-29.504-63.488H63.936v-256h86.016q24-67.008 70.016-120.992L176.96 192l222.016-128 43.008 75.008q70.016-12.992 140 0z m24 87.008l-12 20-22.016 39.008-44.992-8q-58.016-11.008-116 0l-44.992 8-34.016-59.008-110.016 64 32.992 59.008-28.992 34.016q-38.016 44.992-58.016 100.992l-15.008 43.008H127.936v128h67.008l16 43.008q10.016 28.992 24 52.992t34.016 48l28.992 34.016-32.992 59.008 110.016 64 34.016-59.008 44.992 8q58.016 11.008 116 0l44.992-8 34.016 59.008 110.016-64-32.992-59.008 28.992-34.016q38.016-46.016 58.016-100.992l15.008-43.008h68v-128h-67.008l-16-43.008q-8.992-27.008-24-52.512t-34.016-48.512l-28.992-34.016 32.992-59.008zM512 292q95.008 2.016 158.496 65.504T736 516q-2.016 95.008-65.504 158.496T512 740q-95.008-2.016-158.496-65.504T288 516q2.016-95.008 65.504-158.496T512 292z m0 64q-68 2.016-112.992 47.008T352 516q2.016 68 47.008 112.992T512 676q68-2.016 112.992-47.008T672 516q-2.016-68-47.008-112.992T512 356z"  ></path></symbol><symbol id="hanma-bpmn-icon-switch-button" viewBox="0 0 1024 1024"><path d="M352 160v70.016q-110.016 59.008-159.488 167.008t-22.496 228.992q31.008 120.992 124 194.496T512.032 896q124.992-2.016 218.016-75.488t124-194.496q27.008-120.992-22.496-228.992t-159.488-167.008V160q139.008 60.992 207.008 188.512t40.992 276.512q-32.992 148.992-144.512 240.512t-263.488 94.496q-152-3.008-264-94.496t-144-239.488q-27.008-150.016 40.992-277.504t207.008-188.512z m160-96q32 0 32 32v320q0 32-32 32t-32-32V96q0-32 32-32z"  ></path></symbol>
`

export const additionalStyle =
`
.custom-svg-element path:not(.render),
.custom-svg-element polygon:not(.render),
.custom-svg-element circle:not(.render){
  display: none;
}
`

/**
 * 设置字段
 * @param {*} modeler
 * @param {*} element
 * @param {*} payload
 */
export async function setFields (modeler, element, payload = {}) {
  // debugger

  const modeling = modeler.get('modeling')
  const moddle = modeler.get('moddle')

  // const extensionElements = moddle.create('bpmn:ExtensionElements')
  let extensionElements = element.businessObject.get('extensionElements')
  if (!extensionElements) {
    extensionElements = moddle.create('bpmn:ExtensionElements')
  }

  // console.log('util', element.businessObject.extensionElements?.values)
  const fields = extensionElements.values || []

  Object.keys(payload).forEach(field => {
    let fieldElement = fields.find(item => item.name === field)
    if (!fieldElement) {
      fieldElement = moddle.create('flowable:Field')
      fieldElement['name'] = field
      extensionElements.get('values').push(fieldElement)
    }
    const valueElement = moddle.create('flowable:string', { body: String(payload[field]) })
    fieldElement.set('string', valueElement)
    // if (!fieldElement) {
    //   extensionElements.get('values').push(fieldElement)
    // }
  })

  modeling.updateProperties(element, {
    extensionElements: extensionElements.get('values')?.length === 0 ? undefined : extensionElements
  })

  // const result = await modeler.saveXML({ format: true })
  // const { xml } = result
  // console.log(xml)
}

/**
 * 获取字段
 * @param {*} bizOjb 这里不能使用element作为参数 可能会有查看$parent属性的场景
 * @returns
 */
export function getFields (bizOjb) {
  const fields = {}
  const values = bizOjb.extensionElements?.values
  if (values && values.length > 0) {
    values.forEach(item => {
      fields[item.name] = item.string?.body
    })
  }
  return fields
}

/**
 * 流程全局校验
 */
export function globalValidate (modeler) {
  const elementRegistry = modeler.get('elementRegistry')
  console.log(elementRegistry)
  let currentElement
  let errorTab
  try {
    elementRegistry.forEach(element => {
      currentElement = element
      const { id, type } = element

      const nodeFields = getFields(element.businessObject)
      const nodeData = {
        ...element.businessObject,
        ...element.businessObject.$attrs
      }
      // console.log('xxxxxxxxxxxxxx', id, type, type === 'bpmn:UserTask' && id === '__initiator__')
      // console.log('xxxxxxxxxxxxxx', nodeFields)
      // console.log('xxxxxxxxxxxxxx', nodeData)

      if (type === 'bpmn:Process') {
        // 全局配置
        if (!nodeFields.model) {
          errorTab = 'BASE'
          throw (new Error('请选择业务模型'))
        }
      }
      if (['bpmn:StartEvent',
        'bpmn:UserTask',
        'bpmn:ReceiveTask',
        'bpmn:ExclusiveGateway',
        'bpmn:ParallelGateway',
        'bpmn:InclusiveGateway',
        'bpmn:EndEvent',
        'bpmn:ServiceTask'
      ].includes(type)) {
        // 开始节点 接收任务 排他网关 并行网关 包容网关 结束节点
        if (!nodeData.name) {
          errorTab = 'BASE'
          throw (new Error('请填写节点名称'))
        }
      }
      if (type === 'bpmn:UserTask' && id === '__initiator__') {
        // 提交节点
        if (!nodeFields.formKey && !nodeFields.appFormKey) {
          errorTab = 'FORM'
          throw (new Error('请配置待办表单'))
        } else if (!nodeFields.formView && !nodeFields.appFormView) {
          errorTab = 'FORM'
          throw (new Error('请配置查看表单'))
        }
      }

      if (type === 'bpmn:UserTask' && id !== '__initiator__') {
        // 用户任务
        if (nodeData.assignee === '${assignee}') {
          let flag = false
          if (nodeData?.extensionElements) {
            const list = nodeData?.extensionElements?.values || []
            flag = list.some(item => { return item.name === 'collectionString' && item?.string?.body && item?.string?.body.split('_')[1] })
          }
          if (!flag) {
            errorTab = 'BASE'
            throw (new Error('请配置人员信息'))
          }
        } else if (!nodeData.assignee) {
          errorTab = 'BASE'
          throw (new Error('请配置人员信息'))
        }
        if (!nodeFields.formKey && !nodeFields.appFormKey) {
          errorTab = 'FORM'
          throw (new Error('请选择待办表单'))
        }
        if (!nodeFields.formView && !nodeFields.appFormView) {
          errorTab = 'FORM'
          throw (new Error('请选择查看表单'))
        }
        if (nodeFields.completionConditionChecked === 'true') {
          if (!nodeData?.loopCharacteristics?.completionCondition?.body) {
            errorTab = 'BASE'
            throw (new Error('请输入终止条件'))
          } else {
            if (!VARIABLE_BUILT_IN_REG.test(nodeData?.loopCharacteristics?.completionCondition?.body)) {
              errorTab = 'BASE'
              throw (new Error('请输入有效的终止条件表达式'))
            }
          }
        }
      }
      if (type === 'bpmn:ServiceTask') {
        if (id.startsWith('Script_')) {
          // 脚本任务
          if (!nodeFields.script) {
            errorTab = 'BASE'
            throw (new Error('请选择执行脚本'))
          }
        } else {
          // 服务任务
          if (!nodeFields.httpServiceId) {
            errorTab = 'BASE'
            throw (new Error('请选择第三方服务'))
          } else if (!nodeFields.path) {
            errorTab = 'BASE'
            throw (new Error('请填写服务路径'))
          }
        }
      }
      // if (type === 'bpmn:ScriptTask') {
      //   // 脚本任务
      //   if (!nodeFields.script) {
      //     throw (new Error('请选择执行脚本'))
      //   }
      // }

      if (type === 'bpmn:ExclusiveGateway') {
        if (element.businessObject?.outgoing?.length < 2) {
          errorTab = 'BASE'
          Message.error('排他网关至少需要两个条件')
          throw (new Error('排他网关至少需要两个条件'))
        }
      }

      if (type === 'bpmn:SequenceFlow' && element.businessObject.sourceRef.$type === 'bpmn:ExclusiveGateway') {
        // 排他网管后的流程线
        if (!element.businessObject.conditionExpression?.body) {
          errorTab = 'BASE'
          throw (new Error('请填写流转条件'))
        }
      }
      if (type !== 'bpmn:SequenceFlow' && element.incoming.find(flow => flow.businessObject.sourceRef.$type === 'bpmn:ExclusiveGateway')) {
        // 排他网关后的节点
        const priority = nodeData.priority || nodeData['flowable:priority'] || undefined
        if (!priority) {
          errorTab = 'BASE'
          throw (new Error('请填写优先级'))
        }
      }
    })
  } catch (err) {
    return {
      valid: false,
      errorTab: errorTab,
      error: err.message,
      element: currentElement
    }
  }

  if (elementRegistry.filter(item => item.type === 'bpmn:EndEvent').length === 0) {
    return {
      valid: false,
      error: '请配置流程结束节点'
    }
  }

  return {
    valid: true
  }
}

/**
 * 获取节点自定义类型
 * @param {*} element
 */
export function getCustomElementType (element) {
  // console.log('element', element)
  const { id, type, _dataAction } = element
  if (type === 'bpmn:UserTask' && id === DEFAULT_SUBMIT_TASK_ID) {
    return 'bpmn:SubmitTask'
  }
  if (type === 'bpmn:ServiceTask' && id.startsWith(DEFAULT_SCRIPT_TASK_ID_PREFIX)) {
    return 'bpmn:ServiceScriptTask'
  }
  if (type === 'bpmn:ServiceTask' && _dataAction === 'create.service-script-task') {
    return 'bpmn:ServiceScriptTask'
  }
  return type
}

/**
 * 获取节点自定义配置
 * @param {*} element
 */
export function getCustomElementConfig (element) {
  const type = getCustomElementType(element)
  // console.log('type', type)
  return elementConfig[type]
}
